﻿using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using ERP.BLL.MaterialApp.Dtos;
using ERP.IDAL.IRepositories.basic;
using ERP.Model.Entities;
using ERP.Common.Model;
using ERP.BLL.Model;
using ERP.Common.Extensions;

namespace ERP.BLL.MaterialApp
{
    public class MaterialService : IMaterialService
    {
        private readonly IMaterialRepository _materialRepository;
        private readonly IDepotRepository _depotRepository;
        private readonly IDepotMaterialRepository _depotMaterialRepository;
        private readonly ICategoryRepository _categoryRepository;

        public MaterialService(
            IMaterialRepository materialRepository,
            IDepotRepository depotRepository,
            IDepotMaterialRepository depotMaterialRepository,
            ICategoryRepository categoryRepository)
        {
            _materialRepository = materialRepository;
            _depotRepository = depotRepository;
            _depotMaterialRepository = depotMaterialRepository;
            _categoryRepository = categoryRepository;
        }

        public List<Guid> GetDepotsByMaterial(Guid materialId)
        {
            return _depotMaterialRepository.GetAllListAsync(t => t.MaterialId == materialId).Result.Select(t => t.DepotId).ToList();
        }

        public List<MaterialDto> GetMaterialList()
        {
            return Mapper.Map<List<MaterialDto>>(_materialRepository.GetAllListAsync().Result);
        }

        public List<MaterialDto> GetMaterialsByCategory(Guid categoryId)
        {
            var categorys = _categoryRepository.GetAllListAsync().Result.ToList();

            var ids = CollectionExt.GetSons(Mapper.Map<List<SimpleTreeModel>>(categorys), categoryId).Select(t => t.Id).ToList();

            return Mapper.Map<List<MaterialDto>>(_materialRepository.GetAllListAsync(t => ids.Contains(t.CategoryId)).Result);
        }

        public List<MaterialDto> GetMaterialsByDepot(Guid depotId)
        {
            var depotMaterials = _depotMaterialRepository.GetAllIncluding(t => t.Material).Where(t => t.DepotId == depotId).Select(t => t.Material);
            return Mapper.Map<List<MaterialDto>>(depotMaterials);
        }

        public int Insert(MaterialDto dto)
        {
            var material = _materialRepository.FirstOrDefaultAsync(t => t.Name == dto.Name).Result;
            return material != null ? 1 : (_materialRepository.Insert(Mapper.Map<Material>(dto)) != null ? 0 : 1);
        }

        public bool UpdateMaterialDepot(Guid materialId, List<DepotMaterialDto> materialDepots)
        {
            var oldUserRoles = _depotMaterialRepository.GetAllListAsync(t => t.MaterialId == materialId).Result;
            oldUserRoles.ForEach(t => _depotMaterialRepository.Delete(t));
            materialDepots.ForEach(t => _depotMaterialRepository.InsertAsync(Mapper.Map<DepotMaterial>(t)));
            return true;
        }

        public void Delete(Guid id)
        {
            _materialRepository.Delete(id);
        }

        public PagedResultModel<MaterialDto> GetMaterialPageList(SearchMaterialModel search)
        {
            var categorys = _categoryRepository.GetAllListAsync().Result.ToList();
            int rowCount;
            if (!search.CategoryId.IsEmpty() && !search.DepotId.IsEmpty())
            {
                var categoryIds = CollectionExt.GetSons(Mapper.Map<List<SimpleTreeModel>>(categorys), search.CategoryId).Select(t => t.Id).ToList();
                var materialIds = _depotMaterialRepository.GetAllListAsync(t => t.DepotId == search.DepotId).Result.Select(t => t.MaterialId);
                return Mapper.Map<List<MaterialDto>>(_materialRepository.LoadPageList(search.PageIndex, search.PageSize, out rowCount, m => categoryIds.Contains(m.CategoryId) && materialIds.Contains(m.Id), t => t.ModifiedTime, true))
                   .ApplyToPage(search.PageIndex, search.PageSize, rowCount);
            }
            else if (!search.CategoryId.IsEmpty())
            {
                var categoryIds = CollectionExt.GetSons(Mapper.Map<List<SimpleTreeModel>>(categorys), search.CategoryId).Select(t => t.Id).ToList();
                return Mapper.Map<List<MaterialDto>>(_materialRepository.LoadPageList(search.PageIndex, search.PageSize, out rowCount, m => categoryIds.Contains(m.CategoryId), t => t.ModifiedTime, true))
                    .ApplyToPage(search.PageIndex, search.PageSize, rowCount);
            }
            else if (!search.DepotId.IsEmpty())
            {
                var materialIds = _depotMaterialRepository.GetAllListAsync(t => t.DepotId == search.DepotId).Result.Select(t => t.MaterialId);
                return Mapper.Map<List<MaterialDto>>(_materialRepository.LoadPageList(search.PageIndex, search.PageSize, out rowCount, m => materialIds.Contains(m.Id), t => t.ModifiedTime, true))
                    .ApplyToPage(search.PageIndex, search.PageSize, rowCount);
            }

            return Mapper.Map<List<MaterialDto>>(_materialRepository.LoadPageList(search.PageIndex, search.PageSize, out rowCount, m => true, t => t.ModifiedTime, true))
                   .ApplyToPage(search.PageIndex, search.PageSize, rowCount);
        }

        public bool Update(MaterialDto dto)
        {
            var material = _materialRepository.UpdateAsync(Mapper.Map<Material>(dto));
            return material != null;

            //t.Name = dto.Name;
            //t.Manufacturer = dto.Manufacturer;
            //t.Packing = dto.Packing;
            //t.SafetyStock = dto.SafetyStock;
            //t.Model = dto.Model;
            //t.Standard = dto.Standard;
            //t.Color = dto.Color;
            //t.Unit = dto.Unit;
            //t.RetailPrice = dto.RetailPrice;
            //t.LowPrice = dto.LowPrice;
            //t.CategoryId = dto.CategoryId;
            //t.Comment = dto.Comment;
            //t.Enabled = dto.Enabled;


        }
    }
}
